using System;
using ServerNET.Server;

namespace ServerNET.Server
{
    public class CPacket
    {
        public int Length;
        public byte[] Data;
        public int Pos; // Using for reading
        public int Id;

        // Constructor
        public CPacket()
        {
            Length = 0;
            Data = new byte[CCommon.MAX_BUFFER_LENGTH];
        }

        // Constructor
        public CPacket(int Id)
        {
            this.Id = Id;
            Length = 8;
            Data = new byte[CCommon.MAX_BUFFER_LENGTH];
            //Data[4] = (byte)Id;
            byte[] b = BitConverter.GetBytes(Id);
            for (int i = 0; i < 4; i++)
            {
                Data[i + 4] = b[i];
            }
        }

        // Clear Buffer
        public void ClearBuffer()
        {
            Length = 0;
        }

        // Check valid packet
        public bool IsValid()
        {
            // Check header
            if (Length < 8)
            {
                return false;
            }

            byte[] Bytes = new byte[4];
            for (int i = 0; i < 4; i++) Bytes[i] = Data[i];
            int n = BitConverter.ToInt32(Bytes, 0);
            if (n < 0 || n >= CCommon.MAX_BUFFER_LENGTH)
            {
                return false;
            }

            return true;
        }

        // Check reading completed
        public bool IsFinishRead()
        {
            // Check header
            if (Length < 8)
            {
                return false;
            }

            //byte[] bytes = { 0, 0, 0, 25 };
            //if (BitConverter.IsLittleEndian)
            //Array.Reverse(bytes);

            // Check length
            byte[] Bytes = new byte[4];
            for (int i = 0; i < 4; i++) Bytes[i] = Data[i];
            int n = BitConverter.ToInt32(Bytes, 0);
            if (n == Length || n < 0 || n >= CCommon.MAX_BUFFER_LENGTH)
            {
                return true;
            }

            // Length out of range
            if (Length >= CCommon.MAX_BUFFER_LENGTH)
            {
                return true;
            }

            // Return
            return false;
        }

        // Write Byte
        public void WriteByte(int Value)
        {
            Data[Length] = (byte)Value;
            Length++;
        }

        // Get Id
        public int GetId()
        {
            //int Value = Data[4]; 
            //if(Value < 0)
            //{
            //    Value += 256;
            //}
            //return Value;	
            byte[] b = new byte[4];
            for (int i = 0; i < 4; i++)
            {
                b[i] = Data[i + 4];
                Pos++;
            }
            return BitConverter.ToInt32(b, 0);
        }

        // Read string at
        public string ReadStringAt(int Pos, int MaxLength)
        {
            this.Pos = Pos + 8;
            return ReadString(MaxLength);
        }

        // Read string
        public string ReadString(int MaxLength)
        {
            string Value = "";
            for (int i = Pos; i < MaxLength + Pos; i++)
            {
                if (Data[i] == 0)
                {
                    break;
                }

                Value += (char)Data[i];
            }
            Pos += MaxLength;

            Value = CCommon.FilterString(Value);

            return Value;
        }

        // Write Int
        public void WriteInt(int Value)
        {
            byte[] b = BitConverter.GetBytes(Value);
            for (int i = 0; i < 4; i++)
            {
                Data[Length] = b[i];
                Length++;
            }
        }

        // Write double
        public void WriteDouble(double Value)
        {
            byte[] b = BitConverter.GetBytes(Value);
            for (int i = 0; i < 8; i++)
            {
                Data[Length] = b[i];
                Length++;
            }
        }

        // Write String
        public void WriteString(string Value, int MaxLength)
        {
            for (int i = 0; i < MaxLength; i++)
            {
                if (Value != null && i < Value.Length)
                {
                    Data[Length] = (byte)Value[i];
                }
                else
                {
                    Data[Length] = 0;
                }
                Length++;
            }
        }

        // Read int at
        public int ReadIntAt(int Pos)
        {
            this.Pos = Pos + 8;

            return ReadInt();
        }

        // Read int
        public int ReadInt()
        {
            byte[] b = new byte[4];
            for (int i = 0; i < 4; i++)
            {
                b[i] = Data[Pos];
                Pos++;
            }
            return BitConverter.ToInt32(b, 0);
        }

        // Read double
        public double ReadDouble()
        {
            byte[] b = new byte[8];
            for (int i = 0; i < 8; i++)
            {
                b[i] = Data[Pos];
                Pos++;
            }
            return BitConverter.ToDouble(b, 0);
        }

        // End Write
        public void EndWrite()
        {
            byte[] b = BitConverter.GetBytes(Length);
            for (int i = 0; i < 4; i++)
            {
                Data[i] = b[i];
            }
        }

        public double ReadDoubleAt(int Pos)
        {
            this.Pos = Pos + 8;
            return ReadDouble();
        }
    }
}
